/**
 * 
 */
package com.googlecode.pcapj;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.bridj.Pointer;

import com.googlecode.pcapj.bridj.Wpcap;
import com.googlecode.pcapj.bridj.pcap_if;

/**
 * The front end class of the Pcap-J library. 
 */
public class PcapJ {
	private Pointer<Byte> errorBuffer;
	private CapturedFactory capturedFactory = new CapturedFactory();
	
	public PcapJ() {
		super();
		errorBuffer = Pointer.allocateBytes(Wpcap.PCAP_ERRBUF_SIZE);
	}
	/**
	 * Gets the device interface list from the local machine.
	 * @return the List<Interface> object.
	 * @throws PcapJIOException 
	 */
	public List<Interface> getAllInterface(){
		ArrayList<Interface> interfaceList = new ArrayList<Interface>();
		Interfaces interfaces = findAllInterface();
		try{
			for (Interface inter : interfaces) {
				interfaceList.add(inter);
			}
			return interfaceList;
			
		}finally{
			try {
				interfaces.close();
			} catch (IOException e) {
				throw new PcapJRuntimeException(e);
			}
		}
	}
	/**
	 * Gets the device interface list from the local machine.
	 * @return the Interfaces object.
	 * @throws PcapJIOException 
	 */
	Interfaces findAllInterface(){
		Pointer<Pointer<pcap_if>> alldevs = Pointer.allocatePointer(pcap_if.class);
		if(Wpcap.pcap_findalldevs_ex(Wpcap.PCAP_SRC_IF_STRING, Pointer.NULL, alldevs, errorBuffer) == -1){
			alldevs.release();
			throw new PcapJRuntimeException(errorBuffer.getCString());
		}
		return new InterfacesImpl(alldevs, capturedFactory);
	}
	/**
	 * Get the device interface with the specified name.
	 * @param name specifies a name.
	 * @return the {@link Interface} object.
	 */
	public Interface getInterface(String name){
		Interface result = null;
		Interfaces interfaces = findAllInterface();
		try{
			for (Interface inter : interfaces) {
				if(name.equals(inter.getName())){
					result = inter;
					break;
				}
			}
			return result;
			
		}finally{
			try {
				interfaces.close();
			} catch (IOException e) {
				throw new PcapJRuntimeException(e);
			}
		}
	}
	/**
	 * Gets a opened dump file.
	 * @param file a dump file. 
	 * @return the DumpFileReader object.  
	 * @throws IOException 
	 */
	public DumpFileReader openDumpFile(File file) throws IOException{
		DumpFileReader dumpFileReader = new DumpFileReaderImpl(file, capturedFactory);
		dumpFileReader.open();
		return dumpFileReader;
	}
	/**
	 * Gets the editable mappings of the data link type and the DataLinkLayer object. 
	 * @return the editable mappings of the data link type and the DataLinkLayer object.
	 */
	public Map<Integer, DataLinkLayer<? extends Packet>> getDataLinkLayers(){
		return capturedFactory.getDetaLinkLayers();
	}
}
